<?php

namespace app\admin\service\insurance;

use app\Request;
use app\admin\model\InsurancePolicy;
use app\admin\model\InsuranceUser;
use app\admin\model\InsuranceConfig;
use app\admin\model\InsuranceReprule;
use app\admin\model\InsuranceReport;
use app\admin\model\InsuranceQe;
use app\admin\model\InsuranceSection;
use app\admin\model\InsuranceAgent;
use app\admin\model\InsuranceQeRule;
use app\common\utils\Crypt;
use app\common\utils\BaiduOcr;

class PolicyService
{
    /**
     * @var InsurancePolicy
     */
    public $model;
    public $config;

    public function __construct()
    {
        // $this->model = new InsurancePolicy();
        $this->model = InsurancePolicy::class;
        $this->config = InsuranceConfig::find(1);
    }

    public $list_fields = [
        'id',
        'num',
        'is_car_damage',
        'cost',
        'vv_tax',
        'create_at',
        'start_at',
        'end_at',
        'status',
        'remark',
        'sale_type',
        'create_time',
        'update_time',
        'agent',
        'agent_factory',
        'third_party_cost',
        'is_billpay',
        'type',
        'car_type',
        'is_transfer_owner',
        'is_driver',
        'is_passenger',
        'is_renewal',
        'is_notice',
        'file',
        'user_id',
        'batch_ident',
        'is_history_single',
        'history_policy_id',
        'cost_jq',
    ];

    // 获取列表
    public function getPageList($where = [], $page = 1, $limit = 20, $sort = 'id desc'){
        $renewal = '';
        $user_where = [];

        foreach ($where as $k => $v) {
            if (in_array('renewal', $v)) {
                $renewal = $v[2];
                unset($where[$k]);
                break;
            }
            if (in_array('create_at', $v)) {
                $create_at = $v[2];
                unset($where[$k]);
                $where[] = ['create_at', '=', strtotime($create_at)];
                break;
            }
            if (in_array('user.insurer', $v)) {
                $user_where[] = ['insurer', 'like', $v[2]];
                unset($where[$k]);
                break;
            }
            if (in_array('user.carno', $v)) {
                $user_where[] = ['carno', '=', Crypt::encrypt(str_replace('%', '', $v[2]))];
                unset($where[$k]);
                break;
            }
        }
        // var_dump(Crypt::encrypt('粤HAU595'));
        // var_dump($where);
        // var_dump($user_where);
        if (count($user_where) > 0) {
            $users = InsuranceUser::where($user_where)->field('id')->select();
            // var_dump($users);
            $ids = [];
            if ($users) {
                foreach ($users as $user) {
                    $ids[] = $user->id;
                }
            }
            if (count($ids) <= 0) {
                return [0, []];
            }
            $where[] = ['user_id', 'in', $ids];
        }
        if (is_numeric($renewal)) {
            switch ($renewal) {
                case 0:
                    $start = strtotime(date('Y-m-d', strtotime('+91 day')));
                    $end = strtotime(date('Y-m-d', strtotime('+365 day')));
                    break;
                case 1:
                    $start = strtotime(date('Y-m-d', strtotime('+30 day')));
                    $end = strtotime(date('Y-m-d', strtotime('+90 day')));
                    break;
                case 2:
                    $start = strtotime(date('Y-m-d'));
                    $end = strtotime(date('Y-m-d', strtotime('+30 day')));
                    break;
                case 3:
                    $start = strtotime(date('Y-m-d', strtotime('-1 day')));
                    $end = strtotime(date('Y-m-d', strtotime('-30 day')));
                    break;
            }

            $count = $this->model::where($where)->where('status', 1)
                        ->where(function($query) use($start, $end){
                            $query->where('end_at', 'between', [$start, $end]);
                        })
                        ->count() ?: 0;
            $list  = $this->model::where($where)->where('status', 1)
                        ->where(function($query) use($start, $end){
                            $query->where('end_at', 'between', [$start, $end]);
                        })
                        ->field($this->list_fields)
                        ->with(['user' => function ($query) use ($user_where) {
                            $query->field(['id', 'insurer', 'carno'])->select();
                        }])
                        ->with(['report' => function ($query) {
                            $query->find();
                        }])
                        ->order($sort)->page($page, $limit)->select() ?: [];
        } else {
            $count = $this->model::where($where)->where('status', 1)->count() ?: 0;
            $list  = $this->model::where($where)->where('status', 1)->field($this->list_fields)
                            ->with(['user' => function ($query) use ($user_where) {
                                $query->field(['id', 'insurer', 'carno'])->find();
                            }])
                            ->with(['report' => function ($query) {
                                $query->find();
                            }])
                            ->order($sort)->page($page, $limit)->select() ?: [];
        }
        foreach ($list as $k => $v) {
            
            $insurer = $v->user->insurer;
            $carno = $v->user->carno;
            if (mb_strlen($insurer) > 3) {
                $v->user->insurer = mb_substr($insurer, 0, 2) . '*' . mb_substr($insurer, -1);
            } else {
                $v->user->insurer = mb_substr($insurer, 0, 1) . '*' . mb_substr($insurer, -1);
            }
            $list[$k]['types'] = $this->model::where('batch_ident', $v->batch_ident)->field('type, id, is_car_damage')->select() ?: [];
            $section = $this->getSection($v, ['id', 'title']);
            $list[$k]['section_id'] = $section['id'] ?? '';
            $list[$k]['section'] = $section['title'] ?? '';
            if (!$v->report) {
                $list[$k]['report'] = [
                    'amount' => '',
                ];
            }
        }
        return [$count, $list];
    }

    // PDF转图片
    public function pdfToImage($pdf_path, $image_path = '/upload/pdf/'){
        $settings = $this->config['settings'];
        $path_root = $_SERVER['DOCUMENT_ROOT'];
        $resolution = 160;
        $quality = 100;
        if ($settings['ocr_type'] == 1) {
            $resolution = 300;
        }

        if (is_dir($path_root . $image_path)) {
            chmod($path_root . $image_path, 0777);
        }
        $images = '';
         
        $imagick = new \Imagick();
        $background = new \ImagickPixel('white');
        // 设置图片分辨率
        $imagick->setResolution($resolution, $resolution);
        // 该函数接受单个参数$quality，该参数保存一个表示图像压缩质量的整数值
        $imagick->setCompressionQuality($quality);
        $imagick->readImage($pdf_path);
        $blankPage = new \Imagick();
        foreach ($imagick as $key => $val) {
            // 设置图片格式并生成png图片
            $val->setImageFormat('png');
            $filename = md5($key.time()) . '.png';
            $file = $path_root . $image_path . $filename;
            if ($key == 0) {
                //一张白纸，作为背景
                $blankPage->newPseudoImage($val->getImageWidth(), $val->getImageHeight() * 2, "canvas:white");
                //设置合并的位置
                $blankPage->compositeImage($val, \Imagick::COMPOSITE_ATOP, 0, 0);
            }
            if ($key == 1) {
                //设置合并的位置
                $blankPage->compositeImage($val, \Imagick::COMPOSITE_OVER, 0, $val->getImageHeight());
                //合并！
                $blankPage = $blankPage->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);
                if ($blankPage->writeImage($file) === true) {
                    // $images[] = $file;
                    $images = "." . $image_path . $filename;
                    break;
                }
                break;
            }
        }
        return $images;
    }

    public function pdfToImage1($pdf_path, $page = 0){
        $settings = $this->config['settings'];
        $path_root = $settings['path_root'] ?: $_SERVER['DOCUMENT_ROOT'];
        $resolution = 160;
        $quality = 100;
        if ($settings['ocr_type'] == 1) {
            $resolution = 300;
        }
        $image_path = "/upload" . '/' . date('Ymd') . '/';
        if (!is_dir($path_root . $image_path)) {
            mkdir($path_root . $image_path, 0777, true);
        }
        chmod($path_root . $image_path, 0777);
        $images = '';
         
        $imagick = new \Imagick();
        $background = new \ImagickPixel('white');
        // 设置图片分辨率
        $imagick->setResolution($resolution, $resolution);
        // 该函数接受单个参数$quality，该参数保存一个表示图像压缩质量的整数值
        $imagick->setCompressionQuality($quality);
        $imagick->readImage($pdf_path);
        $blankPage = new \Imagick();
        foreach ($imagick as $key => $val) {
            // 设置图片格式并生成png图片
            $val->setImageFormat('png');
            $filename = md5($key.time()) . '.png';
            $file = $path_root . $image_path . $filename;
            if ($key == $page) {
                //一张白纸，作为背景
                $blankPage->newPseudoImage($val->getImageWidth(), $val->getImageHeight(), "canvas:white");
                //设置合并的位置
                $blankPage->compositeImage($val, \Imagick::COMPOSITE_ATOP, 0, 0);
                $blankPage = $blankPage->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);
                if ($blankPage->writeImage($file) === true) {
                    // $images[] = $file;
                    $images = "." . $image_path . $filename;
                    break;
                }
                break;
            }
        }
        return $images;
    }

    // OCR识别
    public function ocrImg($image){
        $settings = $this->config['settings'];
        $appcode = $settings['ali_appcode'];
        $base64 = $this->image2Base64($image);
        $host = "https://gjbsb.market.alicloudapi.com";
        $path = "/ocrservice/advanced";
        $method = "POST";
        $headers = array();
        array_push($headers, "Authorization:APPCODE " . $appcode);
        //根据API的要求，定义相对应的Content-Type
        array_push($headers, "Content-Type".":"."application/json; charset=UTF-8");
        $querys = "";
        $bodys = "{\"img\":\"$base64\",\"url\":\"\",\"prob\":false,\"charmessage\":false,\"rotate\":false,\"table\":false}";
        $url = $host . $path;

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, false);
        if (1 == strpos("$".$host, "https://"))
        {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        curl_setopt($curl, CURLOPT_POSTFIELDS, $bodys);
        $res = curl_exec($curl);
        
        // if (is_array($res)) {
        //     $target = $res;
        // } else {
            $target = json_decode($res, true);
        // }
        return $target;
        if (!is_array($target)) {
            return [];
        }

        $target = $this->getOcrData($target);
        $target['image'] = $image;
        $target['file'] = $file;
        // $data = [
        //     'type' => $target['type'],
        //     'data' => $target,
        // ];
        return $target;
    }

    // 图片转base64
    public function image2Base64($img){
        $file = file_get_contents($img);
        $data = base64_encode($file);
        return $data;
    }

    // 整理OCR数据
    public function getOcrData($data){
        $res = [];
        $content = $data['content'];
        if (str_contains($content, '商业保险保险单')) {
            $type = 1;
        } else if (str_contains($content, '强制保险单')) {
            $type = 0;
        } else if (str_contains($content, '驾乘人员')) {
            $type = 2;
        }
        $contents = explode(' ', $content);
        $res = $this->ocrData($contents, $type);
        $res['type'] = $type;

        return $res;
        $fields = ['id', 'type', 'p_key', 'p_type', 'type', 'keyword', 'reg', 'content_row_num', 'is_rep', 'content_rep_rule'];
        $where = ['status' => 1, 'p_type' => $type];
        $rep_rule = InsuranceReprule::where($where)->field($fields)->select()->toArray();
        $car_type = $this->getCarTypeList();
        foreach ($rep_rule as $rk => $rv) {
            $row_num = 0;
            $row_key = '';
            $rule = [];
            $flag = false;
            foreach ($contents as $ck => $cv) {
                $str = $cv;
                if (empty($str)) continue;
                if ($flag && $row_key != '') {
                    if ($row_num < $rv['content_row_num']) {
                        $row_num++;
                        continue;
                    }
                    if ($rv['p_key'] == 8) { // 车船税
                        if (!str_contains($contents[$ck + 1], '完税凭证号')) {
                            $row_num = 0;
                            $row_key = '';
                            $rule = [];
                            $flag = false;
                            continue;
                        }
                    }
                    if ($rv['p_key'] == 15) { // 车辆类型
                        $ct = 0;
                        foreach ($car_type as $ckk => $cvv) {
                            if (str_contains($str, $cvv['title'])) {
                                $ct = $cvv['id'];
                                break;
                            }
                        }
                        $rep_rule[$rk]['word'] = $ct;
                        $row_num = 0;
                        $row_key = '';
                        $flag = false;
                        break;
                    }
                    $rep_rule[$rk]['word'] = $str;
                    $row_num = 0;
                    $row_key = '';
                    $flag = false;
                    break;
                }
                $is_exist = false;
                switch ($rv['type']) {
                    case 0:
                        $is_exist = $str == $rv['keyword'];
                        break;
                    case 1:
                        $is_exist = str_contains($str, $rv['keyword']);
                        break;
                    case 2:
                        $is_exist = preg_match($rv['reg'], $str);
                        break;
                }
                if (!$is_exist) continue;

                if ($rv['content_row_num'] == 0) {
                    $rep_rule[$rk]['word'] = $str;
                    break;
                } else {
                    $flag = true;
                    $row_num++;
                    $row_key = $rk;
                }
            }
        }
        foreach ($rep_rule as $k => $v) {
            if (empty($v['word'])) continue;
            $str = $v['word'];
            if ($v['is_rep'] == 0) continue;
            foreach ($v['content_rep_rule'] as $crr) {
                if ($crr['sou'] == '.*') {
                    $str = $crr['rep'];
                } else if (str_contains($crr['sou'], '/')) {
                    $str = preg_replace($crr['sou'], $crr['rep'], $str);
                } else {
                    $str = str_replace($crr['sou'], $crr['rep'], $str);
                }
            }
            $rep_rule[$k]['word'] = $str;
        }

        foreach ($rep_rule as $k => $v) {
            $res[InsuranceReprule::$p_keys[$v['p_key']]] = !empty($v['word']) ? $v['word'] : '';
        }

        return $res;
    }

    // 匹配费用
    public function setQe($ids) {
        $settings = $this->config['settings'];
        $res = $this->model::whereIn('id', $ids)->select();
        $success_num = 0;
        $fail_num = 0;
        try{
            $sum = 0;
            $suffixs = [0 => 'jq', 1 => 'sy', 2 => 'jc'];
            foreach ($res as $k => &$v) {
                // 已结费不匹配
                if ($v['is_billpay'] == 1) {
                    $fail_num++;
                    continue;
                }
                $v_suffix = $suffixs[$v['type']];
                // 匹配险种
                $res[$k]['types'] = $this->model::where('batch_ident', $v->batch_ident)->field('type, id, is_car_damage, car_type')->select() ?: [];
                $section = $this->getSection($res[$k]);
                // echo '<pre>';
                // var_dump($res[$k]);
                if (empty($section)) {
                    $fail_num++;
                    continue;
                }
                // if (empty($v['car_type'])) {
                //     $car_type = $this->model::where('batch_ident', $v->batch_ident)->where('car_type', 'not null')->column('car_type');
                //     $car_type = $car_type['car_type'] ?? 0;
                // }
                // if (is_numeric($v['car_type'])) {
                //     $v['car_type'] = 0;
                // } if (is_string($v['car_type'])) {
                // }
                // echo $section['id'];
                // $car_type = str_contains($v['car_type'], '货车') ? 1 : 0;
                // if ($car_type == 0)
                //     $car_type = str_contains($v['car_type'], '特种') ? 2 : 0;

                // 匹配政策
                $create_at = strtotime($v['create_at']);
                $qe = InsuranceQe::where('section_id', $section['id'])
                                    ->where('car_type', $v['car_type'] ?? $car_type)
                                    ->where('is_transfer_owner', $v['is_transfer_owner'] ?? 0)
                                    ->where('vaild_start_at', '<=', $create_at)
                                    ->where('vaild_end_at', '>=', $create_at)
                                    ->where('status', 1)
                                    ->find();
                // $qe = InsuranceQe::where(['section_id' => $section['id']])->find();
                if (empty($qe)) {
                    $fail_num++;
                    continue;
                }
                // echo 123;
                $ratings = [];
                if (!empty($qe['rating'])) {
                    $mins = $qe['rating']['min'] ?? [];
                    $maxs = $qe['rating']['max'] ?? [];
                    $is_renewals = $qe['rating']['is_renewal'] ?? [];
                    $after_taxs = $qe['rating']['after_tax'] ?? [];
                    $auto_coefficient_min = $row['rating']['auto_coefficient_min'] ?? [];
                    $auto_coefficient_max = $row['rating']['auto_coefficient_max'] ?? [];
                    $type = $qe['rating']['type'] ?? [];
                    foreach ($mins as $k1 => $v1) {
                        $ratings[] = [
                            'min' => $v1 ?? '',
                            'max' => $maxs[$k1] ?? '',
                            'is_renewal' => $is_renewals[$k1] ?? '',
                            'after_tax' => $after_taxs[$k1] ?? '',
                            'auto_coefficient_min' => $auto_coefficient_min[$k1] ?? '',
                            'auto_coefficient_max' => $auto_coefficient_max[$k1] ?? '',
                            'type' => $type[$k1] ?? ''
                        ];
                    }
                }

                $sum_point = 0;
                
                $agent = InsuranceAgent::where(['name' => $v['agent'], 'status' => 1])->find();
                $agent && $agent['reduce_percentage_point'] > 0 && $sum_point += $agent['reduce_percentage_point'];
                
                // 匹配政策规则
                $sum_point += $this->sumQePoint($v, $qe);

                $cost = !empty($v['cost']) ? $v['cost'] : 0;
                $cost_jc = !empty($v['cost_jc']) ? $v['cost_jc'] : 0;

                // $tax_after = 0; // 税后
                $tax_after = $qe['tax_after_'.$v_suffix]; // 保单初始税后
                $tax_after_jq = $qe['tax_after_jq']; // 交强险初始税后;
                // 根据规则减税后
                $is_reduce = false; // 是否减税
                $is_reduce_jq = false; // 是否减税
                foreach($qe['red_point_keys'] as $rpk => $rpk_v) {
                    $suffix = substr($rpk_v, -2);
                    if ($suffix == $v_suffix) {
                        $is_reduce = true;
                    }
                    if ($suffix == 'jq') {
                        $is_reduce_jq = true;
                    }
                }
                // 检测车慧达评分设置税后
                if (count($ratings > 0)) {
                    foreach ($ratings as $k1 => $rating) {
                        if ($v['chd_rating'] >= $rating['min'] 
                            && $v['chd_rating'] <= $rating['max'] 
                            && $v['is_renewal'] == $rating['is_renewal'] 
                            && $v['auto_coefficient'] >= $rating['auto_coefficient_min']
                            && $v['auto_coefficient'] <= $rating['auto_coefficient_max']
                            && $rating['after_tax'] > 0){
                            $tax_after = $rating['after_tax'];
                            break;
                        }
                    }
                }
                $red_point_me = $tax_after + $qe['tax_after_me']; // 保单初始税后ME
                if ($is_reduce) {
                    $tax_after -= $sum_point;
                }
                if ($is_reduce_jq) {
                    $tax_after_jq -= $sum_point;
                }
                // 根据规则减税后
                // foreach($qe['red_point_keys'] as $rpk => $rpk_v) {
                //     $suffix = substr($rpk_v, -2);
                //     if ($suffix == $v_suffix) {
                //         $tax_after = $qe[$rpk_v] - $sum_point;
                //         $red_point_me = $qe[$rpk_v];
                //     }
                //     if ($suffix == 'jq') {
                //         $tax_after_jq = $qe[$rpk_v] - $sum_point;
                //     }
                // }

                // 代理费 to me
                // $amount_me = $cost > 0 ? round(($qe['tax_after_'.$v_suffix] + $qe['tax_after_me']) / 100 * $cost, 2) : 0;
                if ($v['type'] == 2) {
                    $red_point_me = $agent['tax_after_me_jc'];
                    $tax_after = $agent['tax_after_ag_jc'];
                }
                $amount_me = $cost > 0 ? round(($red_point_me) / 100 * $cost, 2) : 0;
                // if ($v['type'] == 2) {
                //     $amount_me = $cost > 0 ? round($agent['tax_after_me_jc'] / 100 * $cost, 2) : 0;
                // }


                // 代理点数
                $red_point = $tax_after;
                // if ($v['type'] == 2) {
                //     $red_point = $agent['tax_after_ag_jc'];
                // }
                // 代理费
                $amount = $cost > 0 ? round($tax_after / 100 * $cost, 2) : 0;
                // if ($v['type'] == 2) {
                //     $amount = $cost > 0 ? round($agent['tax_after_ag_jc'] / 100 * $cost, 2) : 0;
                // }

                // 商业有车损 上次单交已结
                $overflow_amount = 0; // 溢出代理费
                if ($v['is_history_single'] == 1 && $v['type'] == 1 && $v['is_car_damage']) {
                    if ($v['cost_jq'] > 0) {
                        $overflow_amount = $v['cost_jq'] * ($tax_after_jq - 3) / 100;
                    } else if ($v['history_policy_id'] > 0){
                        $history_policy = $this->model::where('id', $v['history_policy_id'])
                                            ->with('report')
                                            ->find();
                    } else {
                        $history_policy = $this->model::where(['batch_ident' => $v['batch_ident'], 'type' => 0])
                                                ->where('end_at', '<', strtotime($v['start_at']))
                                                ->with('report')
                                                ->find();
                    }
                    if (!empty($history_policy)) {
                        $overflow_amount = $history_policy->report->amount - $history_policy['cost'] * 0.03;
                    }
                }
                $amount_me -= $overflow_amount;
                $amount -= $overflow_amount;
                
                
                $scharge = $cost > 0 ? round($agent['scharge_point_'.$v_suffix] / 100 * $cost / $settings['tax_point'], 2) : 0;
                // $scharge_jc = $cost_jc > 0 ? round($agent['scharge_point_jc'] / 100 * $cost_jc / $settings['tax_point'], 2) : 0;
                $report = InsuranceReport::where(['policy_id' => $v['id']])->find();
                if (empty($report)) {
                    $report = new InsuranceReport();
                    $report->policy_id = $v['id'];
                }
                $scharge_company = round($cost / $settings['tax_point'] * $settings['scharge_company_point_'.$v_suffix] / 100, 2) ?? 0;
                // 费用
                $report->amount_me = $amount_me;
                $report->red_point_me = $red_point_me;
                $report->amount = $amount;
                $report->red_point = $red_point;
                $report->scharge = $scharge;
                // $report->scharge_jc = $scharge_jc;
                $report->scharge_company = $scharge_company;
                $report->overflow_amount = $overflow_amount;
                $report->save();
                $success_num++;
            }
        } catch (\Exception $e) {
            $result['code'] = 0;
            $result['msg'] = $e->getMessage();
            return $result;
        }
        $result = [
            'code' => 0,
            'msg' => '成功'.$success_num.'条'.'失败'.$fail_num.'条',
        ];
        if ($success_num > 0) {
            $result['code'] = 1;
        } 
        return $result;
    }

    // 统计点数
    public function sumQePoint($data, $qe){
        $is_yh = str_contains($data['user']['carno'], '粤H') ? 1 : 0;
        $is_bind_jc = 0;
        foreach ($data['types'] as $k => $v) { 
            if ($v['type'] == 2) {
                $is_bind_jc = 1;
                break;
            }
        }
        $is_bind_sc = !empty($data['is_driver']) ? 1 : 0;
        $age_min = $data['idcard'] > 0 && ($this->getAgeByidcard($data['idcard']) ?: 0);
        $third_party_min = $data['third_party_cost'] ?: 0;
        $is_transfer_owner = $data['is_transfer_owner'] == 1 ? 1 : 0;

        $sum = 0;
        $rules = [];
        $insWhere = [
            'status' => 1,
            'is_yh' => 2,
        ];
        $ruel1 = InsuranceQeRule::whereIn('id', $qe['rule_ids'])->where($insWhere)->find();
        if ($ruel1 && $is_yh == 0) {
            $sum += $ruel1['reduce_percentage_point'];
        }
        $rules[] = $ruel1;
        $insWhere = [
            'status' => 1,
            'is_bind_jc' => 2,
            'is_bind_sc' => 0
        ];
        $ruel1 = InsuranceQeRule::whereIn('id', $qe['rule_ids'])->where($insWhere)->find();
        if ($ruel1 && $is_bind_jc == 0) {
            $sum += $ruel1['reduce_percentage_point'];
        }
        $rules[] = $ruel1;
        $insWhere = [
            'status' => 1,
            'is_bind_jc' => 2,
            'is_bind_sc' => 2
        ];
        $ruel1 = InsuranceQeRule::whereIn('id', $qe['rule_ids'])->where($insWhere)->find();
        if ($ruel1 && $is_bind_jc == 0 && $is_bind_sc == 0) {
            $sum += $ruel1['reduce_percentage_point'];
        }
        $rules[] = $ruel1;
        $insWhere = [
            'status' => 1,
            ['age_min', '>', 0]
        ];
        $ruel1 = InsuranceQeRule::whereIn('id', $qe['rule_ids'])->where($insWhere)->find();
        if ($ruel1 && $age_min < $ruel1['age_min']) {
            $sum += $ruel1['reduce_percentage_point'];
        }
        $rules[] = $ruel1;
        $insWhere = [
            'status' => 1,
            ['third_party_min', '>', 0]
        ];
        $ruel1 = InsuranceQeRule::whereIn('id', $qe['rule_ids'])->where($insWhere)->find();
        if ($ruel1 && $third_party_min < $ruel1['third_party_min']) {
            $sum += $ruel1['reduce_percentage_point'];
        }
        $rules[] = $ruel1;

        return $sum;
    }

    // 根据身份证获取年龄
    public function getAgeByidcard($idcard){
        # 1.从身份证中获取出生日期
        $id = $idcard;//身份证
        # 1.1判断身份证号码为15位或者18位，如果都不是则报错
        if(strlen($id)!=15 && strlen($id)!=18){
            return false;
        }
        $brithday = strtotime(substr($id, 6, 8).'-'.substr($id, 10, 2).'-'.substr($id, 12, 2));//出生日期截取
        # 2.格式化[出生日期]
        $Year = date('Y', $brithday);//yyyy
        $Month = date('m', $brithday);//mm
        $Day = date('d', $brithday);//dd
        // echo $Year.'-'.$Month.'-'.$Day;
        # 3.格式化[当前日期]
        $current_Y = date('Y');//yyyy
        $current_M = date('m');//mm
        $current_D = date('d');//dd
        
        # 4.计算年龄()
        $age = $current_Y - $Year;//今年减去生日年
        if($Month > $current_M || $Month == $current_M && $Day > $current_D){//深层判断(日)
            $age--;//如果出生月大于当前月或出生月等于当前月但出生日大于当前日则减一岁
        }
        # 返回

        return $age;
    }

    // 获取险种
    public function getSection($policy, $fields = '*'){
        $where = [];
        $where['status'] = 1;
        $where['is_car_damage'] = 0;
        $where['type_sy'] = 0;
        $where['type_jq'] = 0;
        // $where['type_jc'] = 0;
        if ($policy['is_history_single'] > 0) {
            $where['is_car_damage'] = $policy['is_car_damage'] == 1 ? 1 : 0;
            $where['type_sy'] = 1;
            if ($policy['cost_jq'] > 0 || $policy['history_policy_id'] > 0) {
                $where['type_jq'] = 1;
            }
        } else {
            foreach ($policy['types'] as $key => $type) {
                switch ($type['type']) {
                    case 1: $where['type_sy'] = 1; break;
                    case 0: $where['type_jq'] = 1; break;
                    // case 2: $where['type_jc'] = 1; break;
                }
                if ($type['is_car_damage'] == 1) {
                    $where['is_car_damage'] = 1;
                }
            }
        }
        // $where['cost_jc'] = $policy['cost_jc'] > 0 ? 1 : 0;
        $section = InsuranceSection::where($where)->field($fields)->find();
        return $section;
    }

    public function getCarTypeList(){
        return [
            ['id' => 1, 'title' => '客车'],
            ['id' => 2, 'title' => '货车'],
            ['id' => 3, 'title' => '特一'],
            ['id' => 4, 'title' => '特二'],
            ['id' => 5, 'title' => '特三'],
            ['id' => 6, 'title' => '驾校车'],
        ];
    }

    public function ocr(){
        $file = input('file');
        $image = input('image');
        $type = '';
        $settings = $this->config['settings'];
        if ($settings['ocr_type'] == 0) {
            $data = $this->ocrImg($image);
            $content = $data['content'];
            if (str_contains($content, '商业保险保险单')) {
                $type = 1;
            } else if (str_contains($content, '强制保险单')) {
                $type = 0;
            } else if (str_contains($content, '驾乘人员')) {
                $type = 2;
            }
            $contents = explode(' ', $content);
            $res = $this->ocrData($contents, $type);
        } else if ($settings['ocr_type'] == 1) {
            // $data = $this->bdOcr($image);
            
            $data = $this->bdOcr($file, ['type' => 'pdf_file']);
            foreach ($data['words_result'] as $k => $v) {
                if (str_contains($v['words'], '商业保险保险单')) {
                    $type = 1;
                } else if (str_contains($v['words'], '强制保险单')) {
                    $type = 0;
                } else if (str_contains($v['words'], '驾乘人员')) {
                    $type = 2;
                }
                if (is_numeric($type)) {
                    break;
                }
            }
            $res = $this->ocrData($data['words_result'], $type, 'words');
            if ($type == 2) {
                $p2 = $this->bdOcr($file, ['type' => 'pdf_file', 'pdf_file_num' => 2]);
                $res1 = $this->ocrData($p2['words_result'], $type, 'words');
                // $res = array_merge($res, $res1);
                $res['create_at'] = $res1['create_at'];
            }
        }
        $res['type'] = $type;
        $res['file'] = $file;
        $res['image'] = $image;

        return $res;
    }

    public function bdOcr($file, $options = []){
        $options['type'] = $options['type'] ?? 'image';
        $options['pdf_file_num'] = $options['pdf_file_num'] ?? 1;
        
        $settings = $this->config['settings'];
        $key = $settings['baidu_key'];
        $secret = $settings['baidu_secret'];

        switch ($options['type']) {
            case 'image':
                break;
            case 'pdf_file':
                $file = $_SERVER['DOCUMENT_ROOT'] . $file;
                break;
        }
        // echo $file;
        $BaiduOcr = new BaiduOcr($key, $secret);
        $base64 = $this->image2Base64($file);
        $rtn = $BaiduOcr->run1($base64, $options);
        return json_decode($rtn, true);
    }

    public function ocrData($data, $p_type, $data_key = ''){
        $res = [];
        $settings = $this->config['settings'];
        $ocr_type = $settings['ocr_type'];

        $fields = ['id', 'type', 'p_key', 'p_type', 'type', 'keyword', 'reg', 'content_row_num', 'is_rep', 'content_rep_rule'];
        $where = ['status' => 1, 'p_type' => $p_type, 'ocr_type' => $ocr_type];
        $rep_rule = InsuranceReprule::where($where)->field($fields)->select()->toArray();
        $car_type = $this->getCarTypeList();
        foreach ($rep_rule as $rk => $rv) {
            $row_num = 0;
            $row_key = '';
            $rule = [];
            $flag = false;
            foreach ($data as $ck => $cv) {
                $str = $data_key == '' ? $cv : $cv[$data_key];
                if (empty($str)) continue;
                if ($flag && $row_key != '') {
                    if ($row_num < $rv['content_row_num']) {
                        $row_num++;
                        continue;
                    }
                    if ($rv['p_key'] == 8) { // 车船税
                        if (!str_contains($data_key == '' ? $data[$ck + 1] : $data[$ck + 1][$data_key], '完税凭证号')) {
                            $row_num = 0;
                            $row_key = '';
                            $rule = [];
                            $flag = false;
                            continue;
                        }
                    }
                    if ($rv['p_key'] == 15) { // 车辆类型
                        $ct = 0;
                        foreach ($car_type as $ckk => $cvv) {
                            if (str_contains($str, $cvv['title'])) {
                                $ct = $cvv['id'];
                                break;
                            }
                        }
                        $rep_rule[$rk]['word'] = $ct;
                        $row_num = 0;
                        $row_key = '';
                        $flag = false;
                        break;
                    }
                    $rep_rule[$rk]['word'] = trim($str);
                    $row_num = 0;
                    $row_key = '';
                    $flag = false;
                    break;
                }
                $is_exist = false;
                switch ($rv['type']) {
                    case 0:
                        $is_exist = $str == $rv['keyword'];
                        break;
                    case 1:
                        $is_exist = str_contains($str, $rv['keyword']);
                        break;
                    case 2:
                        $is_exist = preg_match($rv['reg'], $str);
                        break;
                }
                if (!$is_exist) continue;

                if ($rv['content_row_num'] == 0) {
                    $rep_rule[$rk]['word'] = trim($str);
                    break;
                } else {
                    $flag = true;
                    $row_num++;
                    $row_key = $rk;
                }
            }
        }
        foreach ($rep_rule as $k => $v) {
            if (empty($v['word'])) continue;
            $str = $v['word'];
            if ($v['is_rep'] == 0) continue;
            foreach ($v['content_rep_rule'] as $crr) {
                if ($crr['sou'] == '.*') {
                    $str = $crr['rep'];
                } else if (str_contains($crr['sou'], '/')) {
                    $str = preg_replace($crr['sou'], $crr['rep'], $str);
                } else {
                    $str = str_replace($crr['sou'], $crr['rep'], $str);
                }
            }
            $rep_rule[$k]['word'] = $str;
        }

        foreach ($rep_rule as $k => $v) {
            $res[InsuranceReprule::$p_keys[$v['p_key']]] = !empty($v['word']) ? $v['word'] : '';
        }
        return $res;
    }
}